# -*- coding: utf-8 -*-
"""
   Copyright (C) 2011 Miguel de Dios

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   higher any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
"""

from Util import *
from Frontend import *
import math, os
from pprint import *

class ListGrid_mode:
	font_color = (255, 255, 255)
	font_size = 15
	fontname = 'Arial'
	grid_columns = 3
	grid_rows = 3
	
	margin_between_cells = 10
	border_cell = 5
	cell_width_and_border = None
	cell_width = None
	cell_height_and_border = None
	cell_height = None
	
	current_row_select = 0
	current_column_select = 0
	offset_rows_page = 0 #The offset move into a grid until exit
	count_rows_roms = 0
	arialFont = None
	top_status_bar_height = 20
	
	last_select_rom = 0
	offset_text = 0.0
	offset_text_dir = "left"
	
	
	def __init__(self, util_param = None, frontend_param = None):
		self.util = util_param
		self.background = None
		self.frontend = frontend_param
		self.frontend.create_default_background()
		self.init_attributes()
		self.init_cell_dimensions()
		self.arialFont = pygame.font.SysFont(self.fontname, self.font_size)
	
	
	def init_attributes(self):
		self.current_row_select = 0
		self.current_column_select = 0
		self.offset_rows_page = 0 #The offset move into a grid until exit
		self.count_rows_roms = 0
		self.last_select_rom = 0
		self.offset_text = 0.0
		self.offset_text_dir = "left"
	
	
	def init_cell_dimensions(self):
		self.count_rows_roms = int(math.ceil(float(len(self.frontend.list_roms)) / float(self.grid_columns)))
		#print("self.count_rows_roms=%i" % self.count_rows_roms)
		
		screen_width = self.util.options["screen_width"]
		screen_height = self.util.options["screen_height"] - self.top_status_bar_height
		
		
		#The cell width is the operation of screen_width minus
		#the margins between the cells and divide for the number
		#of columns
		#For example:
		#  a screen with 3 cells
		#  This is the structure in ascii.
		#
		#   |--------------------------------------------------|
		#   | margin [cell] margin [cell] margin [cell] margin | 
		#   |--------------------------------------------------|
		#
		# Ever (with all amount cells) between the cells there are number margins equal to number of cells minus one.
		# And Ever (with all amount cells) there are two margins in the both sides of screen.
		self.cell_width_and_border = (screen_width - ((self.grid_columns - 1 + 2) * self.margin_between_cells)) / self.grid_columns
		self.cell_width = self.cell_width_and_border - (2 * self.border_cell)
		
		#And for the cell_heights are the equal operations.
		self.cell_height_and_border = (screen_height - ((self.grid_rows - 1 + 2) * self.margin_between_cells)) / self.grid_rows
		#20px for the title in the footer
		self.cell_height = self.cell_height_and_border - (2 * self.border_cell) - 20
	
	
	def paint_background(self):
		"""Paint the background screen-centered"""
		screen_width = self.util.options["screen_width"]
		screen_height = self.util.options["screen_height"]
		background_y = (screen_height - self.frontend.default_background.get_height()) / 2
		background_x = (screen_width - self.frontend.default_background.get_width()) / 2
		self.frontend.screen.blit(self.frontend.default_background, (background_x, background_y))
	
	
	def paint_rom_name(self, x, y, rom, select_rom):
		current_rom = self.frontend.list_roms[rom][1]
		
		tempImage = self.arialFont.render(current_rom, False, self.font_color)
		
		pos_x = self.margin_between_cells * (x + 1) + self.cell_width_and_border * x
		pos_y = self.top_status_bar_height + self.margin_between_cells * (y + 1) + self.cell_height_and_border * (y + 1) - 20
		
		#Margins
		pos_x += 5
		pos_y -= 2
		
		#Crop the text
		if self.cell_width < tempImage.get_width():
			tempImage2 = pygame.Surface((self.cell_width, tempImage.get_height()), pygame.SRCALPHA, 32)
			tempImage2.convert_alpha()
			tempImage2.set_alpha(255)
			if rom == select_rom:
				if self.last_select_rom != select_rom:
					self.offset_text = 0.0
					self.offset_text_dir = "left"
				else:
					if self.offset_text_dir == "left":
						self.offset_text -= 40.0 / self.frontend.framesPerSecond
					else:
						self.offset_text += 40.0 / self.frontend.framesPerSecond
				
				tempImage2.blit(tempImage, (round(self.offset_text), 0))
				
				if self.offset_text_dir == "left":
					if self.cell_width - tempImage.get_width() >= self.offset_text:
						self.offset_text_dir = "right"
				else:
					if self.offset_text >= 0:
						self.offset_text_dir = "left"
				
			else:
				tempImage2.blit(tempImage, (0,0))
			tempImage = tempImage2
			
			self.frontend.screen.blit(tempImage, (pos_x, pos_y))
		else:
			if rom == select_rom:
				self.offset_text = 0.0
				self.offset_text_dir = "left"
			self.frontend.screen.blit(tempImage, (pos_x, pos_y))
		
		self.last_select_rom = select_rom
	
	
	def paint_grid(self, select_rom):
		tempImage = self.arialFont.render("Mode: " + self.frontend.list_modes[self.frontend.current_mode].upper() + \
			" Listed " + str(len(self.frontend.list_roms)) + " roms", False, self.font_color)
		self.frontend.screen.blit(tempImage, (2, 2))
		
		
		count = self.offset_rows_page * self.grid_columns
		
		for row in range(0, self.grid_rows):
			for column in range(0, self.grid_columns):
				if count >= len(self.frontend.list_roms):
					break
				# +1 because the pygame have a crap with the borders.
				x = self.margin_between_cells * (column + 1) + self.cell_width_and_border * column
				y = self.top_status_bar_height + self.margin_between_cells * (row + 1) + self.cell_height_and_border * row 
				rect = pygame.Rect(x, y, self.cell_width_and_border, self.cell_height_and_border)
				
				if (column == self.current_column_select) and (row == self.current_row_select):
					pygame.draw.rect(self.frontend.screen, (255, 0, 0), rect, self.border_cell)
				else:
					pygame.draw.rect(self.frontend.screen, (255, 255, 255), rect, self.border_cell)
				
				# -1 because the pygame have a crap with the borders.
				snap = self.frontend.load_snap(count, None, \
					(self.cell_width + self.border_cell - 1, self.cell_height + self.border_cell - 1))
				if self.frontend.last_snap_found:
					pos_x = x + (self.border_cell / 2) + 1
					if snap.get_width() < self.cell_width:
						pos_x += (self.cell_width - snap.get_width()) / 2
					
					pos_y = y + (self.border_cell / 2) + 1
					if snap.get_height() < self.cell_height:
						pos_y += (self.cell_height - snap.get_height()) / 2
					
					self.frontend.screen.blit(snap, (pos_x, pos_y))
					snap = None
				self.paint_rom_name(column, row, count, select_rom)
				count += 1
			
			#Grid with less roms of cells in grid. Example 3x3 and only 5 roms
			if (count >= len(self.frontend.list_roms)) \
				and ((self.grid_columns * self.grid_rows) > len(self.frontend.list_roms)):
				break
			
			if count >= len(self.frontend.list_roms):
				count = 0
	
	
	def move_select_rom(self, select_rom, key):
		#print("move_select_rom")
		#print("select_rom = %i" % select_rom)
		#print("len(self.frontend.list_roms) = %i" % len(self.frontend.list_roms))
		columns_last_row = len(self.frontend.list_roms) % self.grid_columns
		if columns_last_row == 0 and len(self.frontend.list_roms) > 0:
			columns_last_row = self.grid_columns
		#print("columns_last_row = %i" % columns_last_row)
		current_row_offscreen = (select_rom / self.grid_columns)
		#print("current_row_offscreen = %i" % current_row_offscreen)
		
		if key == K_UP:
			#print("K_UP")
			self.current_row_select -= 1
			if self.current_row_select < 0:
				if self.count_rows_roms > self.grid_rows:
					self.offset_rows_page -= 1
					self.current_row_select = 0
				else:
					#When there is less rows than the grid, example 3x3 and 2 roms
					self.current_row_select = self.count_rows_roms - 1
			
			# Check if the first
			if current_row_offscreen == 0:
				if self.current_column_select < columns_last_row:
					# Check
					# [ ][ ][ ]
					# [ ][^][ ][ ]
					select_rom = len(self.frontend.list_roms) - columns_last_row + self.current_column_select 
				else:
					# Check
					# [ ][ ][ ]
					# [ ][ ][ ][^]
					self.current_column_select = columns_last_row - 1
					select_rom = (len(self.frontend.list_roms) - 1)
					
			else:
				select_rom -= self.grid_columns
			
			
		elif key == K_DOWN:
			#print("K_DOWN")
			self.current_row_select += 1
			if self.current_row_select == self.grid_rows:
				if self.count_rows_roms > self.grid_rows:
					self.offset_rows_page += 1
					self.current_row_select = self.grid_rows - 1
				else:
					#When there is less rows than the grid, example 3x3 and 2 roms
					self.current_row_select = 0
			else:
				if self.count_rows_roms <= self.current_row_select:
					#When there is less rows than the grid, example 3x3 and 2 roms
					self.current_row_select = 0
			
			#print("self.current_row_select=%i" % self.current_row_select)
			
			if current_row_offscreen == (self.count_rows_roms - 1):
				#print("It is the last row")
				#It is the last row
				# Check if the last file not is complete
				# [ ][ ][ ][ ]
				# [ ][ ][V]
				select_rom = 0 + self.current_column_select
			elif current_row_offscreen == (self.count_rows_roms - 2):
				#print("It is the previous last row")
				#It is the previous last row
				# [ ][ ][ ][V]
				# [ ][ ][ ]
				
				if self.current_column_select >= columns_last_row:
					select_rom = (len(self.frontend.list_roms) - 1)
					
					self.current_column_select = columns_last_row - 1
				else:
					select_rom += self.grid_columns
			else:
				#print("general")
				select_rom += self.grid_columns
		elif key == K_RIGHT:
			if current_row_offscreen == (self.count_rows_roms - 1):
				#It is the last row
				
				# [ ][ ][ ][ ]
				# [ ][ ][>]
				
				if (columns_last_row - 1) == self.current_column_select:
					self.current_column_select = 0
					select_rom = (current_row_offscreen * self.grid_columns)
				else:
					self.current_column_select += 1
					select_rom += 1
			else:
				if (self.grid_columns - 1) == self.current_column_select:
					self.current_column_select = 0
					select_rom = (current_row_offscreen * self.grid_columns)
				else:
					self.current_column_select += 1
					select_rom += 1
		elif key == K_LEFT:
			if current_row_offscreen == (self.count_rows_roms - 1):
				#It is the last row
				
				# [ ][ ][ ][ ]
				# [<][ ][ ]
				
				if (self.current_column_select == 0):
					self.current_column_select = columns_last_row - 1
					select_rom += columns_last_row - 1
				else:
					self.current_column_select -= 1
					select_rom -= 1
			else:
				if (self.current_column_select == 0):
					self.current_column_select = self.grid_columns - 1
					select_rom += self.grid_columns - 1
				else:
					self.current_column_select -= 1
					select_rom -= 1
		
		
		#Normalize select_rom
		select_rom %= len(self.frontend.list_roms)
		#print("select_rom=%i" % select_rom)
		
		#Normalice self.offset_rows_page
		self.offset_rows_page %= self.count_rows_roms
		
		#print("")
		
		return select_rom
	
	
	def reset_pos_in_the_grid(self, select_rom):
		self.current_column_select = select_rom % self.grid_columns
		
		if self.count_rows_roms > self.grid_rows:
			self.current_row_select = 0
			self.offset_rows_page = select_rom / self.grid_columns
		else:
			self.offset_rows_page = 0
			self.current_row_select = select_rom / self.grid_columns
	
	def run(self):
		time_hold_button = 0
		select_rom = self.util.load_value_db("internal_selected_rom", 0)
		if select_rom > 0:
			#If the select rom from the last execution is other that
			#the first rom
			
			self.reset_pos_in_the_grid(select_rom)
		
		exit_var = False
		
		last_pressed_key = None
		last_rom = None
		last_time_move = 0
		sleep_when_pressed_same_key = 800
		change_direction = False
		while not exit_var:
			now = pygame.time.get_ticks()
			
			if self.util.options['shutdown_hold_button']:
				if time_hold_button:
					if ((now - time_hold_button) / 1000) > 1:
						self.frontend.show_shutdown_message()
						#If the computer does not shutdown maybe the
						#user stoped to hold the button
						#reset all flags and time counters
						time_hold_button = 0
			
			if last_pressed_key is None:
				id_rom_screensaver = self.frontend.screen_saver()
				
				if id_rom_screensaver:
					select_rom = self.frontend.translate_idrom_to_arraykey(id_rom_screensaver)
					
					self.reset_pos_in_the_grid(select_rom)
					self.frontend.execute_rom(select_rom)
			else:
				self.frontend.reset_screen_saver()
			
			
			self.frontend.screen.fill((0, 0, 0))
			
			self.paint_background()
			self.paint_grid(select_rom)
			
			ekey = self.frontend.get_events()
			
			if ekey < 0:
				ekey = -ekey
				if ekey == K_1 or ekey == K_RETURN:
					if self.util.options['shutdown_hold_button']:
						time_hold_button = (now - time_hold_button) / 1000
						if time_hold_button < 5:
							time_hold_button = 0
							self.frontend.execute_rom(select_rom)
					else:
						self.frontend.execute_rom(select_rom)
				last_pressed_key = None
				last_time_to_wait_move = now
			elif ekey > 0:
				last_pressed_key = None
				if ekey == K_ESCAPE:
					exit_var = True
				elif ekey == K_q:
					self.frontend.can_shutdown = False
					exit_var = True
				elif ekey == K_UP:
					if last_pressed_key != ekey:
						sleep_when_pressed_same_key = 800
						last_time_move = now
						change_direction = True
				elif ekey == K_DOWN:
					if last_pressed_key != ekey:
						sleep_when_pressed_same_key = 800
						last_time_move = now
						change_direction = True
				elif ekey == K_RIGHT:
					if last_pressed_key != ekey:
						sleep_when_pressed_same_key = 800
						last_time_move = now
						change_direction = True
				elif ekey == K_LEFT:
					if last_pressed_key != ekey:
						sleep_when_pressed_same_key = 800
						last_time_move = now
						change_direction = True
				elif ekey == K_1 or ekey == K_RETURN:
					time_hold_button = now
				elif ekey == K_c or ekey == K_LALT:
					# New feature: add/remove from favorities
					select_rom = self.frontend.toggle_fav(select_rom)
					self.global_count_roms = len(self.frontend.list_roms)
				elif ekey == K_SPACE:
					# New feature: show favorities or full list rom
					select_rom = self.frontend.switch_mode(select_rom)
					self.global_count_roms = len(self.frontend.list_roms)
					#force_update
					select_rom = 0
					self.init_attributes()
					self.init_cell_dimensions()
				
				select_rom = self.move_select_rom(select_rom, ekey)
				
				last_pressed_key = ekey
			#END IF KEYDOWN
			
			if (last_pressed_key is not None) and (not change_direction):
				if (sleep_when_pressed_same_key + last_time_move) < now:
					select_rom = self.move_select_rom(select_rom, ekey)
					
					#Acelerate the movement across the list
					if sleep_when_pressed_same_key > 100:
						sleep_when_pressed_same_key -= 100
					last_time_move = now
			change_direction = False
			
			self.frontend.waitFrame()
			pygame.display.update()